use crate::rtsp::rtp::rtcp::errors::RtcpError;
use crate::rtsp::rtp::rtcp::rtcp_header::RtcpHeader;
use crate::rtsp::rtp::utils::{Marshal, Unmarshal};
use byteorder::BigEndian;
use bytes::BytesMut;
use bytesio::bytes_reader::BytesReader;
use bytesio::bytes_writer::BytesWriter;

// 以下注释展示了 RTCP APP 包的二进制结构，每一行代表 32 位（4 字节）
//  0                   1                   2                   3
//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |V=2|P|    ST   |   PT=APP=204  |             length            |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |                           SSRC/CSRC                           |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |                          name (ASCII)                         |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |                   application-dependent data                ...
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

// RtcpApp 结构体，用于表示 RTCP APP 类型的数据包
#[derive(Debug, Clone, Default)]
pub struct RtcpApp {
    // RTCP 通用头
    pub header: RtcpHeader,
    // 同源标识符
    pub ssrc: u32,
    // 应用程序特定的名称
    pub name: BytesMut,
    // 应用程序特数据
    pub app_data: BytesMut,
}

impl Unmarshal<BytesMut, Result<Self, RtcpError>> for RtcpApp {
    fn unmarshal(raw_data: BytesMut) -> Result<Self, RtcpError>
    where
        Self: Sized,
    {
        // 创建一个字节读取器，用于从可变字节缓冲区中读取数据
        let mut reader = BytesReader::new(raw_data);

        // 创建一个默认的 RtcpApp 实例
        let mut rtcp_app = RtcpApp::default();
        // 调用 RtcpHeader 的 unmarshal 方法解析 RTCP 头部
        rtcp_app.header = RtcpHeader::unmarshal(&mut reader)?;

        // 以大端字节序读取 4 字节作为 SSRC/CSRC
        rtcp_app.ssrc = reader.read_u32::<BigEndian>()?;
        // 读取 4 字节作为应用程序特定的名称
        rtcp_app.name = reader.read_bytes(4)?;
        // 根据 RTCP 头部中的长度字段，读取相应长度的应用程序特定数据
        // RTCP 头部的 length 字段以 32 位字为单位，所以要乘以 4 得到字节数
        rtcp_app.app_data = reader.read_bytes(rtcp_app.header.length as usize * 4)?;

        // 返回解析成功的 RtcpApp 实例
        Ok(rtcp_app)
    }
}

impl Marshal<Result<BytesMut, RtcpError>> for RtcpApp {
    fn marshal(&self) -> Result<BytesMut, RtcpError> {
        // 创建一个默认的字节写入器
        let mut writer = BytesWriter::default();

        // 调用 RtcpHeader 的 marshal 方法将 RTCP 头部序列化为字节数据
        let header_bytesmut = self.header.marshal()?;
        // 将序列化后的 RTCP 头部字节数据写入字节写入器
        writer.write(&header_bytesmut[..])?;

        // 以大端字节序将 SSRC/CSRC 写入字节写入器
        writer.write_u32::<BigEndian>(self.ssrc)?;
        // 将应用程序特定的名称写入字节写入器
        writer.write(&self.name[..])?;
        // 将应用程序特定的数据写入字节写入器
        writer.write(&self.app_data[..])?;

        // 提取字节写入器中的当前字节数据并返回
        Ok(writer.extract_current_bytes())
    }
}
